home *** CD-ROM | disk | FTP | other *** search
- #ifndef MSC
-
- /* Non-MSC Version */
-
- #if (defined(M_I86CM) || defined(M_I86LM) || defined(M_I86HM))
-
- /* NOTE: These procedures should only be used for
- large data model programs (i.e., Compact, Large, Huge) */
-
- #include <stddef.h>
- #include <stdlib.h>
- #include "alloc.h"
-
- extern ATABLE AllocationTable [] ; /* Provide storage for block pointers */
- extern SUNIT TABLESIZE ; /* Maximum allocation table size */
- extern SUNIT MBSize ; /* Default allocation block size */
- extern SUNIT NEntry ; /* Number of table entries */
-
- void *realloc ( ap, nbytes )
-
- void *ap ; /* Pointer to block to be reallocated */
- size_t nbytes ; /* New size of block */
-
- /*
- +---------------------------------------+
- | |
- | Reallocate block procedure |
- | |
- +---------------------------------------+
- */
-
- {
- HEADER *Header ;
- HEADER *LHeader ;
- HEADER *CheckBlock () ;
- HEADER *AllocateBlock () ;
- SUNIT *bptr ;
- SUNIT *nptr ;
- SUNIT *tptr ;
- SUNIT *FindBlock () ;
- SUNIT offset ;
- SUNIT noffset ;
- SUNIT bsize ;
- SUNIT nsize ;
- SUNIT allocsize ;
- void CollapseBlocks () ;
- void FreeEmptyBlocks () ;
- void NormalizeMBSize () ;
- void free () ;
- int i ;
-
- /* Check pointer passed is O.K. */
-
- if ((Header = CheckBlock ( ap, &offset )) == NULL )
- return ( NULL ) ;
-
- /* If block was previously free'ed, reallocate it */
-
- bptr = (SUNIT *) ap - 1 ;
- bsize = *bptr & ~FREE ;
- *bptr = bsize ;
-
- /* Check for 'virtual' free */
-
- if ( nbytes == 0 ) {
- free ( ap ) ;
- return ( NULL ) ;
- } ;
-
- /* Calculate number of bytes needed. */
-
- allocsize = SSIZE * (( nbytes - 1 ) / SSIZE + 1 ) ;
- if ( allocsize > MAXALLOC )
- return ( NULL ) ;
-
- /* Check if there is room in a lower level block */
-
- for ( i = 0; i < NEntry ; i++ ) {
- if ( AllocationTable [i].Header == Header )
- break ;
- CollapseFreeBlocks ( AllocationTable [i].Header ) ;
- if ((nptr = FindBlock (AllocationTable [i].Header,allocsize)) != NULL){
- memcpy ( (char *) nptr, (char *) (bptr+1), min (bsize,allocsize)) ;
- *bptr |= FREE ;
- Header->Collapsed = FALSE ;
- CollapseFreeBlocks ( Header ) ;
- FreeEmptyBlocks ( Header ) ;
- return ( (void *) nptr ) ;
- } ;
- } ;
-
- /* Check previous allocation in this block to see if enough room */
-
- CollapseFreeBlocks ( Header ) ;
- noffset = HSIZE ;
- while ( noffset < offset ) {
- nptr = (SUNIT *) Header + noffset/SSIZE ;
- nsize = *nptr & ~FREE ;
- if ( (*nptr & FREE) ) {
- if ( (nsize ) >= allocsize ||
- ((noffset + nsize + SSIZE ) == offset &&
- (nsize + bsize + SSIZE ) >= allocsize )) {
- *nptr = allocsize ;
- memcpy ( (char *) (nptr + 1), (char *) (bptr+1),
- min ( bsize, allocsize ) ) ;
- tptr = nptr ;
- noffset += allocsize + SSIZE ;
- nptr = (SUNIT *) Header + noffset/SSIZE ;
- if ( nsize >= allocsize ) {
- *bptr |= FREE ;
- if ( nsize > allocsize )
- *nptr = (nsize - allocsize - SSIZE) | FREE ;
- }
- else if ( nsize + bsize + SSIZE > allocsize )
- *nptr = (bsize + nsize - allocsize) | FREE ;
- Header->Collapsed = FALSE ;
- return ( (void *) (tptr+1) ) ;
- } ;
- } ;
- noffset += nsize+SSIZE ;
- } ;
-
- /* Not enough space below so check current allocation */
-
- if ( allocsize == bsize )
- return ( ap ) ;
- if ( allocsize < bsize ) {
- *bptr = allocsize ;
- offset += allocsize+SSIZE ;
- *((SUNIT *)Header+offset/SSIZE) = (bsize - allocsize - SSIZE) | FREE ;
- Header->Collapsed = FALSE ;
- return ( ap ) ;
- } ;
-
- /* Check next allocation to see if free and if enough total room */
-
- noffset = offset + bsize + SSIZE ;
- if ( noffset < Header->BytesUsed ) {
- nptr = (SUNIT *) Header + noffset/SSIZE ;
- nsize = *nptr & ~FREE ;
- if ( (*nptr & FREE) && (nsize + bsize + SSIZE) >= allocsize ) {
- *bptr = allocsize ;
- if ( nsize + bsize + SSIZE > allocsize ) {
- noffset = offset + allocsize + SSIZE ;
- nptr = (SUNIT *) Header + noffset/SSIZE ;
- *nptr = (bsize + nsize - allocsize) | FREE ;
- Header->Collapsed = FALSE ;
- } ;
- return ( ap ) ;
- } ;
- } ;
-
- /* Check if there is room in this or higher level block */
-
- for ( ; i < NEntry ; i++ ) {
- CollapseFreeBlocks ( AllocationTable [i].Header ) ;
- if ((nptr = FindBlock (AllocationTable [i].Header,allocsize)) != NULL){
- memcpy ( (char *) nptr, (char *) (bptr+1), bsize ) ;
- *bptr |= FREE ;
- Header->Collapsed = FALSE ;
- return ( (void *) nptr ) ;
- } ;
- } ;
-
- /* Normalize MBSize */
-
- NormalizeMBSize () ;
-
- /* Check if we can expand this block */
-
- if ( Header == AllocationTable [NEntry-1].Header &&
- offset + bsize + SSIZE >= Header->BytesUsed )
- *bptr |= FREE ;
- LHeader = AllocationTable [NEntry-1].Header ;
- if ( ExpandBlock ( LHeader, allocsize ) ) {
- AllocationTable [NEntry-1].Size = LHeader->BytesUsed ;
- if ((nptr=FindBlock ( LHeader, allocsize ) ) != NULL ) {
- if ( nptr != (bptr+1) ) {
- memcpy ( (char *) nptr, (char *) (bptr+1), bsize ) ;
- *bptr |= FREE ;
- }
- else
- *bptr &= ~FREE ;
- Header->Collapsed = FALSE ;
- return ( (void *) nptr ) ;
- } ;
- }
- else
- *bptr &= ~FREE ;
-
- /* Allocate new block and free space in old block */
-
- if ( NEntry == TABLESIZE )
- return ( NULL ) ;
- nsize = MBSize * (( allocsize + HSIZE + SSIZE - 1 ) / MBSize + 1 ) ;
- if ((AllocationTable [NEntry].Header = AllocateBlock (nsize)) == NULL )
- return ( NULL ) ;
- *bptr |= FREE ;
- Header->Collapsed = FALSE ;
-
- Header = AllocationTable [NEntry].Header ;
- AllocationTable [NEntry++].Size = Header->BytesUsed ;
- nptr = FindBlock ( Header, allocsize ) ;
- memcpy ( (char *) nptr, (char *) (bptr+1), bsize ) ;
- return ( (void *) nptr ) ;
- }
- #endif
- #endif
-